package org.openbpm.bus.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.openbpm.base.api.aop.annotion.CatchErr;
import org.openbpm.base.api.exception.BusinessException;
import org.openbpm.base.api.response.impl.ResultMsg;
import org.openbpm.base.core.util.StringUtil;
import org.openbpm.base.rest.util.RequestUtil;
import org.openbpm.bus.api.service.EtechBusinessObjectService;
import org.openbpm.bus.rest.controller.BusinessObjectController;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping({"/etech/businessObject/"})
public class EtechBusinessObjectController  extends BusinessObjectController {
    @Resource(name= "etechBusinessObjectService")
    EtechBusinessObjectService etechBusinessObjectService;

    @RequestMapping({"exportBusObject"})
    @CatchErr("exportBusObject异常")
    public void exportBusObject(HttpServletRequest request, HttpServletResponse response, String ids) throws Exception {
        // 导出文件用zip压缩
        // businessObjectXmlList -> businessObjectXml (relationJson + busTable(busColumn(ctrJson) ) )
        String[] objIds = RequestUtil.getStringAryByStr(request, "ids");
        if (ArrayUtil.isEmpty(objIds)) {
            return;
        }
        String zipName = "busObject" + DateUtil.format(new Date(), "yyyy_MMdd_HHmm");
        Map<String, String> exprotXml = this.etechBusinessObjectService.exportBusObject(objIds);
        downLoadFile(request, response, exprotXml, zipName);
    }

    private static final String ROOT_PATH = "temp" + File.separator + "tempZip";

    private static void downLoadFile(HttpServletRequest request, HttpServletResponse response, Map<String, String> fileContentMap, String zipName) throws Exception {
        String zipPath = getWebContextPath() + ROOT_PATH + File.separator + zipName;
        for (Map.Entry<String, String> ent : fileContentMap.entrySet()) {
            String fileName = (String)ent.getKey();
            String content = (String)ent.getValue();
            String filePath = zipPath + File.separator + fileName;
            FileUtil.writeUtf8String(content, filePath);
        }
        File file = ZipUtil.zip(zipPath);
        FileUtil.del(zipPath);
        RequestUtil.downLoadFile(response, file);
        FileUtil.del(file);
    }

    @RequestMapping({"importBusObject"})
    @CatchErr("importBusObject异常")
    public ResultMsg<List<Map<String, Object>>> importBusObject(MultipartHttpServletRequest request, HttpServletResponse response) throws Exception {
        MultipartFile fileLoad = request.getFile("xmlFile");
        String name = fileLoad.getOriginalFilename();
        String unZipFilePath = getWebContextPath() + File.separator + "temp" + File.separator + "unzip";
        try {
            String fileDir = StringUtils.substringBeforeLast(name, ".");
            String originalFilename = fileLoad.getOriginalFilename();
            String destPath = unZipFilePath + File.separator + originalFilename;
            File file = FileUtil.file(destPath);
            FileUtil.mkParentDirs(file);
            fileLoad.transferTo(file);
            ZipUtil.unzip(file);
            unZipFilePath = unZipFilePath + File.separator + fileDir;
            String fileName = unZipFilePath + "/businessObject.xml";
            String busXml = FileUtil.readUtf8String(fileName);
            if (StringUtil.isEmpty(busXml)) {
                throw new BusinessException("导入的文件缺少 businessObject");
            }
            busXml = checkXmlFormat(busXml);
            List<Map<String, Object>> perviewList = this.etechBusinessObjectService.importPreview(busXml);
            return getSuccessResult(perviewList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            File unzipfile = new File(unZipFilePath);
            if (unzipfile.exists()) {
                FileUtil.del(unzipfile);
            }
        }
    }
    //检查xml文件格式是否正确
    public String  checkXmlFormat(String xml) throws Exception {
        String firstName = "businessObjectXmlList";
        String nextName = "businessObjectXml";
        Document doc = DocumentHelper.parseText(xml);
        Element root = doc.getRootElement();
        String msg = "导入文件格式不对";
        if (!root.getName().equals(firstName)){
            throw new Exception(msg);
        }

        List<Element> itemLists = root.elements();
        for (Element elm : itemLists) {
            if (!elm.getName().equals(nextName)){
                throw new Exception(msg);
            }
        }
        return xml;
    }
    @RequestMapping({"importSave"})
    @CatchErr("importSave异常")
    public ResultMsg<String> importSave(@RequestBody List<JSONObject> overViewList) throws Exception {
        // 输入参数overViewList为importBusObject的输出数据
        if (CollectionUtil.isEmpty(overViewList)) {
            throw new RuntimeException("导入的数据不能为空！");
        }
        this.etechBusinessObjectService.importSave(overViewList);
        return getSuccessResult("导入成功!");
    }

    protected static String getWebContextPath() {
        // 增加容器环境支持
        String path = ClassUtil.getClassPath();
        if (path.indexOf("WEB-INF") != -1) {
            path = path.substring(0, path.lastIndexOf("WEB-INF"));
        } else if(path.indexOf("classes") != -1){
            path = path.substring(0, path.lastIndexOf("classes"));
        } else {
            path = System.getProperty("user.dir");
            if(StringUtil.isEmpty(path)){
                File tfile = new File("");
                try{
                    path = tfile.getAbsolutePath();
                }catch (Exception e){
                    path = System.getProperty("user.home");
                }
            }
        }
        path = StringUtil.trimSuffix(path, "/");
        return path;
    }
}
